﻿// Decompiled with JetBrains decompiler
// Type: Microsoft.InfoCards.TokenCreationParameter
// Assembly: infocard, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// MVID: 8E14765A-6610-409A-BA36-099A0642905D
// Assembly location: E:\git\ALLIDA\windll\infocard.exe

using Microsoft.InfoCards.Diagnostics;
using System;
using System.Collections.Generic;
using System.IO;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

namespace Microsoft.InfoCards
{
  internal class TokenCreationParameter : IXmlSerializable
  {
    private TokenFactoryCredentialType m_credentialType;
    private EndpointAddress m_epr;
    private string m_hint;
    private Dictionary<CredentialSelectorType, CredentialSelector> m_selectorMap;

    public TokenCreationParameter()
    {
      this.m_selectorMap = new Dictionary<CredentialSelectorType, CredentialSelector>();
    }

    public TokenFactoryCredentialType CredentialType
    {
      get
      {
        return this.m_credentialType;
      }
      set
      {
        this.m_credentialType = value;
      }
    }

    public EndpointAddress Epr
    {
      get
      {
        return this.m_epr;
      }
      set
      {
        this.m_epr = value;
      }
    }

    public Dictionary<CredentialSelectorType, CredentialSelector> CredentialSelectors
    {
      get
      {
        return this.m_selectorMap;
      }
    }

    public bool IsComplete()
    {
      if ((EndpointAddress) null == this.m_epr)
        return false;
      bool flag = true;
      if (this.m_credentialType == TokenFactoryCredentialType.X509CertificateCredential || this.m_credentialType == TokenFactoryCredentialType.SelfIssuedCredential)
        flag = flag && this.m_selectorMap.Count > 0;
      return flag;
    }

    public void ThrowIfNotComplete()
    {
      if (!this.IsComplete())
        throw InfoCardTrace.ThrowHelperError((Exception) new SerializationIncompleteException(this.GetType()));
    }

    public void Serialize(BinaryWriter writer)
    {
      this.ThrowIfNotComplete();
      writer.Write((int) this.m_credentialType);
      Utility.SerializeString(writer, this.m_hint);
      Utility.SerializeString(writer, TokenCreationParameter.CreateEprXmlString(this.m_epr));
      writer.Write(this.m_selectorMap.Count);
      if (this.m_selectorMap.Count <= 0)
        return;
      foreach (CredentialSelector credentialSelector in this.m_selectorMap.Values)
        credentialSelector.Serialize(writer);
    }

    public void Deserialize(BinaryReader reader)
    {
      TokenFactoryCredentialType factoryCredentialType = (TokenFactoryCredentialType) reader.ReadInt32();
      string str = Utility.DeserializeString(reader);
      EndpointAddress eprFromString = TokenCreationParameter.CreateEprFromString(Utility.DeserializeString(reader));
      int num = reader.ReadInt32();
      Dictionary<CredentialSelectorType, CredentialSelector> dictionary = new Dictionary<CredentialSelectorType, CredentialSelector>();
      for (int index = 0; index < num; ++index)
      {
        CredentialSelector credentialSelector = new CredentialSelector();
        credentialSelector.Deserialize(reader);
        dictionary.Add(credentialSelector.Type, credentialSelector);
      }
      this.m_credentialType = factoryCredentialType;
      this.m_epr = eprFromString;
      this.m_selectorMap = dictionary;
      this.m_hint = str;
      this.ThrowIfNotComplete();
    }

    private static EndpointAddress CreateEprFromString(string value)
    {
      using (MemoryStream memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(value)))
      {
        using (XmlDictionaryReader readerWithQuotas = Utility.CreateReaderWithQuotas((Stream) memoryStream))
        {
          try
          {
            return EndpointAddress.ReadFrom(readerWithQuotas);
          }
          catch (InfoCardBaseException ex)
          {
            throw;
          }
          catch (Exception ex)
          {
            if (!InfoCardTrace.IsFatal(ex))
              throw InfoCardTrace.ThrowHelperError((Exception) new InvalidCardException(SR.GetString("ServiceInvalidCredentialSelector"), ex));
            throw;
          }
        }
      }
    }

    private static string CreateEprXmlString(EndpointAddress address)
    {
      using (MemoryStream memoryStream = new MemoryStream())
      {
        using (XmlWriter writer = (XmlWriter) new XmlTextWriter((Stream) memoryStream, Encoding.Unicode))
        {
          address.WriteTo(AddressingVersion.WSAddressing10, writer);
          writer.Flush();
          memoryStream.Flush();
          return Encoding.Unicode.GetString(memoryStream.GetBuffer(), 2, Convert.ToInt32(memoryStream.Length - 2L));
        }
      }
    }

    public System.Xml.Schema.XmlSchema GetSchema()
    {
      return (System.Xml.Schema.XmlSchema) null;
    }

    public void WriteXml(XmlWriter writer)
    {
      if (writer == null)
        throw InfoCardTrace.ThrowHelperArgumentNull(nameof (writer));
      InfoCardTrace.ThrowInvalidArgumentConditional(!this.IsComplete(), "IsComplete");
      writer.WriteStartElement("TokenService", "http://schemas.xmlsoap.org/ws/2005/05/identity");
      this.m_epr.WriteTo(AddressingVersion.WSAddressing10, writer);
      writer.WriteStartElement("UserCredential", "http://schemas.xmlsoap.org/ws/2005/05/identity");
      if (!string.IsNullOrEmpty(this.m_hint))
      {
        writer.WriteStartElement("DisplayCredentialHint", "http://schemas.xmlsoap.org/ws/2005/05/identity");
        writer.WriteString(this.m_hint);
        writer.WriteEndElement();
      }
      switch (this.m_credentialType)
      {
        case TokenFactoryCredentialType.UserNamePasswordCredential:
          this.WriteUserNameCredential(writer);
          break;
        case TokenFactoryCredentialType.SelfIssuedCredential:
          this.WriteSelfIssuedCredential(writer);
          break;
        case TokenFactoryCredentialType.X509CertificateCredential:
          this.WriteX509CertificateCredential(writer);
          break;
        case TokenFactoryCredentialType.KerberosCredential:
          this.WriteKerberosCredential(writer);
          break;
        default:
          InfoCardTrace.ThrowInvalidArgumentConditional(true, "CredentialType");
          break;
      }
      writer.WriteEndElement();
      writer.WriteEndElement();
    }

    public void WriteUserNameCredential(XmlWriter writer)
    {
      writer.WriteStartElement("UsernamePasswordCredential", "http://schemas.xmlsoap.org/ws/2005/05/identity");
      if (this.m_selectorMap.ContainsKey(CredentialSelectorType.UserNameSelector))
        this.m_selectorMap[CredentialSelectorType.UserNameSelector].WriteXml(writer);
      writer.WriteEndElement();
    }

    public void WriteKerberosCredential(XmlWriter writer)
    {
      writer.WriteStartElement("KerberosV5Credential", "http://schemas.xmlsoap.org/ws/2005/05/identity");
      writer.WriteEndElement();
    }

    public void WriteSelfIssuedCredential(XmlWriter writer)
    {
      writer.WriteStartElement("SelfIssuedCredential", "http://schemas.xmlsoap.org/ws/2005/05/identity");
      if (this.m_selectorMap.ContainsKey(CredentialSelectorType.SelfIssuedCardIdSelector))
        this.m_selectorMap[CredentialSelectorType.SelfIssuedCardIdSelector].WriteXml(writer);
      writer.WriteEndElement();
    }

    public void WriteX509CertificateCredential(XmlWriter writer)
    {
      writer.WriteStartElement("X509V3Credential", "http://schemas.xmlsoap.org/ws/2005/05/identity");
      if (this.m_selectorMap.ContainsKey(CredentialSelectorType.X509CertificateIssuerNameSelector) && this.m_selectorMap.ContainsKey(CredentialSelectorType.X509CertificateIssuerSerialNoSelector))
      {
        writer.WriteStartElement("X509Data", "http://www.w3.org/2000/09/xmldsig#");
        writer.WriteStartElement("X509IssuerSerial", "http://www.w3.org/2000/09/xmldsig#");
        this.m_selectorMap[CredentialSelectorType.X509CertificateIssuerNameSelector].WriteXml(writer);
        this.m_selectorMap[CredentialSelectorType.X509CertificateIssuerSerialNoSelector].WriteXml(writer);
        writer.WriteEndElement();
        writer.WriteEndElement();
      }
      else if (this.m_selectorMap.ContainsKey(CredentialSelectorType.X509CertificateKeyHashSelector))
      {
        writer.WriteStartElement("X509Data", "http://www.w3.org/2000/09/xmldsig#");
        this.m_selectorMap[CredentialSelectorType.X509CertificateKeyHashSelector].WriteXml(writer);
        writer.WriteEndElement();
      }
      writer.WriteEndElement();
    }

    public void ReadXml(XmlReader reader)
    {
      if (!reader.IsStartElement("TokenService", "http://schemas.xmlsoap.org/ws/2005/05/identity"))
        throw InfoCardTrace.ThrowHelperError((Exception) new XmlException(SR.GetString("UnexpectedElement")));
      reader.ReadStartElement();
      if (!(reader.LocalName == "EndpointReference"))
        throw InfoCardTrace.ThrowHelperError((Exception) new InvalidCardException(SR.GetString("ServiceInvalidCredentialSelector")));
      try
      {
        this.m_epr = EndpointAddress.ReadFrom(XmlDictionaryReader.CreateDictionaryReader(reader));
      }
      catch (InfoCardBaseException ex)
      {
        throw;
      }
      catch (Exception ex)
      {
        if (!InfoCardTrace.IsFatal(ex))
          throw InfoCardTrace.ThrowHelperError((Exception) new InvalidCardException(SR.GetString("ServiceInvalidCredentialSelector"), ex));
        throw;
      }
      if ((EndpointAddress) null != this.m_epr && (EndpointAddress) null == Utility.DeriveMexAddress(this.m_epr))
        throw InfoCardTrace.ThrowHelperError((Exception) new InvalidCardException(SR.GetString("ServiceEprDoesNotHaveValidMetadata")));
      if (reader.LocalName == "UserCredential")
        reader.ReadStartElement();
      if (reader.LocalName == "DisplayCredentialHint")
        this.m_hint = this.ReadDisplayCredentialHint(reader);
      switch (reader.LocalName)
      {
        case "UsernamePasswordCredential":
          this.CredentialType = TokenFactoryCredentialType.UserNamePasswordCredential;
          if (!reader.IsEmptyElement)
          {
            while (reader.Read() && (!(reader.LocalName == "UsernamePasswordCredential") || reader.NodeType != XmlNodeType.EndElement))
            {
              if (reader.LocalName == "Username")
              {
                CredentialSelector credentialSelector = new CredentialSelector();
                credentialSelector.ReadXml(reader);
                if (credentialSelector.IsComplete())
                {
                  this.CredentialSelectors.Add(credentialSelector.Type, credentialSelector);
                  break;
                }
                break;
              }
            }
            break;
          }
          reader.ReadStartElement();
          break;
        case "KerberosV5Credential":
          this.CredentialType = TokenFactoryCredentialType.KerberosCredential;
          if (!reader.IsEmptyElement)
          {
            while (reader.Read() && (!(reader.LocalName == "KerberosV5Credential") || reader.NodeType != XmlNodeType.EndElement))
            {
              if (reader.LocalName == "UserPrincipalName")
              {
                CredentialSelector credentialSelector = new CredentialSelector();
                credentialSelector.ReadXml(reader);
                if (credentialSelector.IsComplete())
                {
                  this.CredentialSelectors.Add(credentialSelector.Type, credentialSelector);
                  break;
                }
                break;
              }
            }
            break;
          }
          reader.ReadStartElement();
          break;
        case "SelfIssuedCredential":
          this.CredentialType = TokenFactoryCredentialType.SelfIssuedCredential;
          reader.ReadStartElement();
          CredentialSelector credentialSelector1 = new CredentialSelector();
          credentialSelector1.ReadXml(reader);
          if (credentialSelector1.IsComplete())
            this.CredentialSelectors.Add(credentialSelector1.Type, credentialSelector1);
          reader.ReadEndElement();
          break;
        case "X509V3Credential":
          this.CredentialType = TokenFactoryCredentialType.X509CertificateCredential;
          this.ReadX509V3CredentialElement(reader);
          reader.ReadEndElement();
          break;
        default:
          throw InfoCardTrace.ThrowHelperError((Exception) new InvalidCardException(SR.GetString("NoAuthenticationServicesInCard")));
      }
      reader.ReadEndElement();
    }

    public string ReadDisplayCredentialHint(XmlReader reader)
    {
      if (!reader.IsStartElement("DisplayCredentialHint", "http://schemas.xmlsoap.org/ws/2005/05/identity"))
        throw InfoCardTrace.ThrowHelperError((Exception) new XmlException(SR.GetString("UnexpectedElement")));
      return reader.ReadElementContentAsString().Trim();
    }

    private void ReadX509V3CredentialElement(XmlReader reader)
    {
      if (!reader.IsStartElement("X509V3Credential", "http://schemas.xmlsoap.org/ws/2005/05/identity"))
        throw InfoCardTrace.ThrowHelperError((Exception) new XmlException(SR.GetString("UnexpectedElement")));
      reader.ReadStartElement();
      if (!("http://www.w3.org/2000/09/xmldsig#" == reader.NamespaceURI) || !("X509Data" == reader.LocalName))
        return;
      while (reader.Read())
      {
        if (reader.IsStartElement("X509IssuerSerial", "http://www.w3.org/2000/09/xmldsig#"))
        {
          reader.ReadStartElement();
          CredentialSelector credentialSelector1 = new CredentialSelector();
          credentialSelector1.ReadXml(reader);
          CredentialSelector credentialSelector2 = new CredentialSelector();
          credentialSelector2.ReadXml(reader);
          if (credentialSelector2.IsComplete() && credentialSelector1.IsComplete())
          {
            this.CredentialSelectors.Add(credentialSelector1.Type, credentialSelector1);
            this.CredentialSelectors.Add(credentialSelector2.Type, credentialSelector2);
          }
          reader.ReadEndElement();
          break;
        }
        if (reader.IsStartElement("KeyIdentifier", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"))
        {
          CredentialSelector credentialSelector = new CredentialSelector();
          credentialSelector.ReadXml(reader);
          if (credentialSelector.IsComplete())
          {
            this.CredentialSelectors.Add(credentialSelector.Type, credentialSelector);
            break;
          }
          break;
        }
      }
      while (!("X509Data" == reader.LocalName) || !("http://www.w3.org/2000/09/xmldsig#" == reader.NamespaceURI) || XmlNodeType.EndElement != reader.NodeType)
      {
        if (!reader.Read())
          return;
      }
      reader.ReadEndElement();
    }
  }
}
